@file:Suppress("DEPRECATED_IDENTITY_EQUALS")

package com.tywj.lib.core.common.util

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Bitmap.CompressFormat
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.PixelFormat
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.text.TextUtils
import android.util.Base64.*
import android.util.Log
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.Target
import com.zxy.tiny.Tiny
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.FileOutputStream

/**
 * <pre>
 *     author : June Yang
 *     time   : 2020/5/7
 *     desc   : bitmap工具类
 *     version: 1.0.0
 * </pre>
 */
object BitmapUtil {

    /**
     * 获取图片（该方法为耗时操作）
     */
    fun getBitmapFromUrl(url: String, width: Int = Target.SIZE_ORIGINAL, height: Int = Target.SIZE_ORIGINAL): Bitmap? {
        return Glide.with(AppUtil.context)
            .asBitmap()
            .load(url)
            .submit(width, height)
            .get()
    }

    /**
     * 将bitmap转换为字节数组(该方法可能为耗时操作)
     */
    fun bitmap2ByteArray(bitmap: Bitmap, quality: Int = 100): ByteArray {
        val output = ByteArrayOutputStream()
        bitmap.compress(CompressFormat.PNG, quality, output)

        val result = output.toByteArray()
        try {
            output.close()
        } catch (e: Exception) {
            LogUtil.printStackTrace(e)
        }

        return result
    }

    /**
     * 压缩图片（耗时操作）
     */
    fun compressToFile(path: String, successAction: (File) -> Unit, failAction: ((Throwable) -> Unit)? = null) {
        Tiny.getInstance().source(path).asFile().compress { isSuccess, outfile, t ->
            if (isSuccess) {
                successAction.invoke(File(outfile))
            } else {
                failAction?.invoke(t)
            }
        }
    }

    /**
     * 压缩图片（耗时操作）
     */
    fun compressToBitamp(path: String, successAction: (Bitmap) -> Unit, failAction: ((Throwable) -> Unit)? = null) {
        Tiny.getInstance().source(path).asBitmap().compress { isSuccess, bitmap, t ->
            if (isSuccess) {
                successAction.invoke(bitmap)
            } else {
                failAction?.invoke(t)
            }
        }
    }

    /**
     * 获取图片类型
     */
    fun getMimeType(path: String): String {
        val options = BitmapFactory.Options()
        options.inJustDecodeBounds = true
        BitmapFactory.decodeFile(path, options)
        val type = options.outMimeType
        if (TextUtils.isEmpty(type)) {
            throw IllegalArgumentException("未能识别的图片")
        } else {
            return type.substring(6, type.length)
        }
    }

    /**
     * bitmaptoFile
     * 注意适配图片路径
     * @param context
     * @param fileName 保存的文件名
     * @param bitmap  bitmap图片
     */
    fun saveBitMapToFile(context: Context?, fileName: String, bitmap: Bitmap): File? {
        var file: File? = null
        if (null == context || TextUtils.isEmpty(fileName)) return file
        var fOut: FileOutputStream? = null
        try {
            file = context.externalCacheDir

            if (file.exists()) {
                file.delete()
                fOut = FileOutputStream(file)
                if (fileName.endsWith(".jpg")) {
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 75, fOut)
                } else {
                    bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut)
                }
                fOut.flush()
                bitmap.recycle()
            }
            return file
        } catch (e: Exception) {
            return null
        } finally {
            if (null != fOut) {
                try {
                    fOut.close()
                } catch (e: Exception) {
                    Log.e("FileSave", "saveDrawableToFile, close error", e)
                }

            }
        }
    }

    /**
     * 图片路径转换为String
     */
    @Synchronized
    fun drawableToByte(drawable: Drawable?): String? {
        if (drawable != null) {
            val bitmap = Bitmap
                .createBitmap(
                    drawable.intrinsicWidth,
                    drawable.intrinsicHeight,
                    if (drawable.opacity !== PixelFormat.OPAQUE) Bitmap.Config.ARGB_8888 else Bitmap.Config.RGB_565
                )
            val canvas = Canvas(bitmap)
            drawable.setBounds(
                0, 0, drawable.intrinsicWidth,
                drawable.intrinsicHeight
            )
            drawable.draw(canvas)
            val size = bitmap.width * bitmap.height * 4

            // 创建一个字节数组输出流,流的大小为size
            val baos = ByteArrayOutputStream(size)
            // 设置位图的压缩格式，质量为100%，并放入字节数组输出流中
            bitmap.compress(CompressFormat.PNG, 100, baos)
            // 将字节数组输出流转化为字节数组byte[]
            val imagedata = baos.toByteArray()
            return encodeToString(imagedata, DEFAULT)
        }
        return null
    }

    /**
     * String 转换成 Drawable
     */
    @Synchronized
    fun byteToDrawable(icon: String): Drawable? {
        val img = decode(icon.toByteArray(), DEFAULT)
        val bitmap: Bitmap
        if (img != null) {
            bitmap = BitmapFactory.decodeByteArray(img, 0, img.size)
            return BitmapDrawable(bitmap)
        }
        return null
    }
}